package com.study.ui.test.test_download

import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import androidx.core.content.FileProvider
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import com.lbj.core.ext.toLog
import com.lbj.core.ext.toToast
import com.lbj.mvvm.update.AppUpdate
import com.lbj.mvvm.update.AppUpdate.TAG_CANCEL
import com.lbj.mvvm.update.net.INetDownloadCallback
import com.lbj.mvvm.update.net.INetManage
import com.study.databinding.DailogApkUpdateBinding
import java.io.File
import java.io.FileInputStream
import java.lang.Exception
import java.math.BigInteger
import java.security.MessageDigest

/**
 * 作者：李炳军
 * 创建日期：2021-04-01  11:38
 * 释义：
 */
class ApkUpdateDialog : DialogFragment() {

    companion object {
        private const val APK_UPDATE_DIALOG_BEAN = "APK_UPDATE_DIALOG_BEAN"
        fun show(act: FragmentActivity, args: DownloadBean) {
            val bundle = Bundle()
            bundle.putSerializable(APK_UPDATE_DIALOG_BEAN, args)
            val dialog = ApkUpdateDialog()
            dialog.arguments = bundle
            dialog.show(act.supportFragmentManager, APK_UPDATE_DIALOG_BEAN)
        }
    }

    private lateinit var binding: DailogApkUpdateBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = DailogApkUpdateBinding.inflate(LayoutInflater.from(context), container, false)
        val result = arguments?.getSerializable(APK_UPDATE_DIALOG_BEAN) as DownloadBean
        binding.result = result
        binding.presenter = Presenter()
        binding.executePendingBindings()
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
    }

    inner class Presenter {
        fun onApkUploadClick(v: View, result: DownloadBean) {
            val file = File(requireActivity().cacheDir, "study.apk")
            v.isEnabled = false
            AppUpdate.getManager()
                .download(result.url, file, object : INetDownloadCallback {
                    override fun success(apkFile: File) {
                        "下载完成：${apkFile.absolutePath}".toLog()
                        dismiss()
                        // 检测md5完整性
                        val md5 = apkFile.md5()
                        "服务器md5:${result.md5}".toLog()
                        "本地校验md5:${md5}".toLog()
                        if (result.md5 == md5) {
                            requireActivity().installApk(apkFile)
                        } else {
                            "Apk不完整".toToast()
                        }
                    }

                    override fun progress(progress: Int) {
                        "下载进度：$progress".toLog()
                        binding.progress = progress
                    }

                    override fun failure(throwable: Throwable) {
                        "下载失败：${throwable.printStackTrace()}".toLog()
                        v.isEnabled = true
                    }
                },TAG_CANCEL)
        }
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        AppUpdate.getManager().cancel(TAG_CANCEL)
    }
}

/**
 * 需要处理 N FileProvider 适配
 * 需要处理 O Install permission 适配 -> 配置权限：android.permission.REQUEST_INSTALL_PACKAGES
 */
fun Activity.installApk(file: File) {
    val intent = Intent()
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    intent.action = Intent.ACTION_VIEW

    // 处理 N FileProvider 适配
    val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        // 添加读写权限
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
        // 与AndroidManifest中 android:authorities="${applicationId}.FileProvider" 保持一致
        FileProvider.getUriForFile(this, "$packageName.FileProvider", file)
    } else {
        Uri.fromFile(file)
    }
    intent.setDataAndType(uri, "application/vnd.android.package-archive")
    startActivity(intent)
}

/**
 * 获取文件的md5值
 */
fun File.md5(): String {
    // 不是文件
    if (!isFile) {
        return ""
    }

    var inStream: FileInputStream? = null
    var digest: MessageDigest? = null
    try {
        digest = MessageDigest.getInstance("MD5")
        inStream = FileInputStream(this)
        var len: Int
        val buffer = ByteArray(1024)
        do {
            len = inStream.read(buffer)
            if (len != -1) {
                digest.update(buffer, 0, len)
            } else {
                break
            }
        } while (true)
    } catch (e: Exception) {
        e.printStackTrace()
        return ""
    } finally {
        try {
            inStream?.close()
        } catch (e: Exception) {
            e.printStackTrace()
            return ""
        }
    }
    // 获取数组
    val byteArr = digest?.digest()
    // 转为16进制
    val bigInteger = BigInteger(1, byteArr)
    return bigInteger.toString(16)
}